/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.editors.entity;

import cn.easyplatform.entities.beans.ResourceBean;
import cn.easyplatform.lang.Nums;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.vos.BizQueryVo;
import cn.easyplatform.studio.vos.FieldVo;
import cn.easyplatform.studio.web.editors.AbstractEntityEditor;
import cn.easyplatform.studio.web.editors.BandboxCallback;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.studio.web.views.impl.AbstractView;
import cn.easyplatform.type.EntityType;
import cn.easyplatform.web.ext.cmez.CMeditor;
import org.quartz.CronExpression;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.KeyEvent;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zul.*;

import java.util.List;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class JobEntityEditor extends AbstractEntityEditor<ResourceBean> {

    private Tabbox tabbox;

    private Textbox entityName;

    private Textbox entityDesp;

    private Checkbox immediate;

    private Combobox clazz;

    private Bandbox expression;

    private Intbox delay;

    private Checkbox checkHoliday;

    private Bandbox user;

    private Bandbox org;

    private Bandbox task;

    private Textbox path;

    private Textbox extension;

    private Textbox backup;

    private Textbox encoding;

    private Textbox dateFormat;

    private Intbox firstRowNum;

    private Intbox lastRowNum;

    private Intbox firstColNum;

    private Intbox lastColNum;

    private Grid properties;

    private Bandbox logic;

    private Bandbox onBefore;

    private Bandbox onAfter;

    /**
     * @param workbench
     * @param entity
     * @param code
     */
    public JobEntityEditor(WorkbenchController workbench, ResourceBean entity,
                           char code) {
        super(workbench, entity, code);
    }

    @Override
    public void create(Object... args) {
        super.create(args);
        Tabpanel tabpanel = new Tabpanel();
        Idspace is = new Idspace();
        is.setHflex("1");
        is.setVflex("1");
        is.setParent(tabpanel);
        Executions.createComponents("~./include/editor/entity/job.zul", is,
                null);
        for (Component comp : is.getFellows()) {
            if (comp.getId().equals("job_tabbox_main")) {
                tabbox = (Tabbox) comp;
                tabbox.addEventListener(Events.ON_SELECT, this);
            } else if (comp.getId().equals("job_textbox_name")) {
                entityName = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                entityName.setValue(entity.getName());
            } else if (comp.getId().equals("job_textbox_desp")) {
                entityDesp = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                entityDesp.setValue(entity.getDescription());
            } else if (comp.getId().equals("job_cmeditor_source")) {
                source = (CMeditor) comp;
                source.setTheme(Contexts.getUser().getEditorTheme());
            } else if (comp.getId().equals("job_switchbox_immediate")) {
                immediate = (Checkbox) comp;
                immediate.addEventListener(Events.ON_CHECK, this);
                immediate
                        .setValue(entity.getProps().get("immediate") == null ? true
                                : entity.getProps().get("immediate")
                                .equalsIgnoreCase("true"));
            } else if (comp.getId().equals("job_switchbox_checkHoliday")) {
                checkHoliday = (Checkbox) comp;
                checkHoliday.addEventListener(Events.ON_CHECK, this);
                checkHoliday
                        .setValue(entity.getProps().get("checkHoliday") == null ? true
                                : entity.getProps().get("checkHoliday")
                                .equalsIgnoreCase("true"));
            } else if (comp.getId().equals("job_combobox_clazz")) {
                clazz = (Combobox) comp;
                String name = entity.getProps().get("class");
                if (Strings.isBlank(name))
                    clazz.setSelectedIndex(0);
                else if (name.endsWith("FileScanerJobWorker"))
                    clazz.setSelectedIndex(1);
                clazz.setDisabled(code != 'C');
                clazz.setReadonly(true);
                if (!clazz.isDisabled())
                    clazz.addEventListener(Events.ON_CHANGE, this);
            } else if (comp.getId().equals("job_bandbox_expression")) {
                expression = (Bandbox) comp;
                expression.addEventListener(Events.ON_CHANGE, this);
                expression.setValue(entity.getProps().get("expression"));
                expression.addEventListener(Events.ON_OPEN, this);
                expression.addEventListener(Events.ON_OK, this);
            } else if (comp.getId().equals("job_intbox_delay")) {
                delay = (Intbox) comp;
                delay.setValue(Nums.toInt(entity.getProps().get("delay"), 60));
                delay.addEventListener(Events.ON_CHANGE, this);
            } else if (comp.getId().equals("job_bandbox_user")) {
                user = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                user.addEventListener(Events.ON_OPEN, this);
                user.addEventListener(Events.ON_OK, this);
                user.setValue(entity.getProps().get("user"));
            } else if (comp.getId().equals("job_bandbox_org")) {
                org = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                org.addEventListener(Events.ON_OPEN, this);
                org.addEventListener(Events.ON_OK, this);
                org.setValue(entity.getProps().get("org"));
            } else if (comp.getId().equals("job_bandbox_task")) {
                task = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                task.addEventListener(Events.ON_OPEN, this);
                task.addEventListener(Events.ON_OK, this);
                task.setValue(entity.getProps().get("task"));
            } else if (comp.getId().equals("job_textbox_path")) {
                path = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                path.setValue(entity.getProps().get("path"));
            } else if (comp.getId().equals("job_textbox_extension")) {
                extension = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                extension.setValue(entity.getProps().get("extension"));
            } else if (comp.getId().equals("job_textbox_encoding")) {
                encoding = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                encoding.setValue(entity.getProps().get("encoding"));
            } else if (comp.getId().equals("job_intbox_firstRowNum")) {
                firstRowNum = (Intbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                firstRowNum.setValue(Nums.toInt(
                        entity.getProps().get("firstRowNum"), 0));
            } else if (comp.getId().equals("job_intbox_lastRowNum")) {
                lastRowNum = (Intbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                lastRowNum.setValue(Nums.toInt(
                        entity.getProps().get("lastRowNum"), 0));
            } else if (comp.getId().equals("job_intbox_firstColNum")) {
                firstColNum = (Intbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                firstColNum.setValue(Nums.toInt(
                        entity.getProps().get("firstColNum"), 0));
            } else if (comp.getId().equals("job_intbox_lastColNum")) {
                lastColNum = (Intbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                lastColNum.setValue(Nums.toInt(
                        entity.getProps().get("lastColNum"), 0));
            } else if (comp.getId().equals("job_textbox_backup")) {
                backup = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                backup.setValue(entity.getProps().get("backup"));
            } else if (comp.getId().equals("job_textbox_dateFormat")) {
                dateFormat = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                dateFormat.setValue(entity.getProps().get("dateFormat"));
            } else if (comp.getId().equals("job_bandbox_logic")) {
                logic = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                logic.addEventListener(Events.ON_OPEN, this);
                logic.addEventListener(Events.ON_OK, this);
                logic.setValue(entity.getProps().get("logic"));
            } else if (comp.getId().equals("job_bandbox_onBefore")) {
                onBefore = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                onBefore.addEventListener(Events.ON_OPEN, this);
                onBefore.addEventListener(Events.ON_OK, this);
                onBefore.setValue(entity.getProps().get("onBefore"));
            } else if (comp.getId().equals("job_bandbox_onAfter")) {
                onAfter = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                onAfter.addEventListener(Events.ON_OPEN, this);
                onAfter.addEventListener(Events.ON_OK, this);
                onAfter.setValue(entity.getProps().get("onAfter"));
            } else if (comp.getId().equals("job_grid_properties"))
                properties = (Grid) comp;
        }
        redraw();
        workbench.addEditor(tab, tabpanel);
    }

    @Override
    protected void redraw() {
        Component row = null;
        if (clazz.getSelectedIndex() == 0) {
            List<Component> children = properties.getRows().getChildren();
            for (int i = 4; i < children.size(); i++)
                children.get(i).setVisible(false);
            row = children.get(3);
            row.setVisible(true);
            entity.getProps().remove("path");
            entity.getProps().remove("extension");
            entity.getProps().remove("encoding");
            entity.getProps().remove("firstRowNum");
            entity.getProps().remove("lastRowNum");
            entity.getProps().remove("firstColNum");
            entity.getProps().remove("lastColNum");
            entity.getProps().remove("backup");
            entity.getProps().remove("dateFormat");
            entity.getProps().remove("logic");
            path.setValue("");
            extension.setValue("");
            encoding.setValue("");
            firstRowNum.setValue(0);
            lastRowNum.setValue(0);
            firstColNum.setValue(0);
            lastColNum.setValue(0);
            backup.setValue("");
            dateFormat.setValue("");
            logic.setValue("");
        } else if (clazz.getSelectedIndex() == 1) {
            List<Component> children = properties.getRows().getChildren();
            for (int i = 4; i < children.size(); i++)
                children.get(i).setVisible(true);
            children.get(3).setVisible(false);
            entity.getProps().remove("task");
            task.setValue("");
            row = children.get(children.size() - 1);
        }
        Component c = onBefore.getPreviousSibling();
        c.detach();
        row.appendChild(c);
        onBefore.detach();
        row.appendChild(onBefore);
        c = onAfter.getPreviousSibling();
        c.detach();
        row.appendChild(c);
        onAfter.detach();
        row.appendChild(onAfter);
    }

    @Override
    protected void dispatch(Event evt) {
        Component c = evt.getTarget();
        if (c instanceof Tab) {
            if (tabbox.getSelectedIndex() == 1 && validate())
                refreshSource();
        } else if (evt.getName().equals(Events.ON_CHANGE)) {
            if (c == clazz) {
                entity.getProps().remove("class");
                if (clazz.getSelectedIndex() > 0)
                    entity.getProps().put("class",
                            "cn.easyplatform.services.job.FileScanerJobWorker");
                redraw();
            } else if (c == entityDesp)
                entity.setDescription(entityDesp.getValue());
            else if (c == entityName)
                entity.setName(entityName.getValue());
            else if (c == task)
                entity.getProps().put("task", task.getValue());
            else if (c == path)
                entity.getProps().put("path", path.getValue());
            else if (c == extension)
                entity.getProps().put("extension", extension.getValue());
            else if (c == encoding)
                entity.getProps().put("encoding", encoding.getValue());
            else if (c == firstRowNum)
                entity.getProps().put("firstRowNum",
                        firstRowNum.getValue() + "");
            else if (c == lastRowNum)
                entity.getProps().put("lastRowNum", lastRowNum.getValue() + "");
            else if (c == firstColNum)
                entity.getProps().put("firstColNum",
                        firstColNum.getValue() + "");
            else if (c == lastColNum)
                entity.getProps().put("lastColNum", lastColNum.getValue() + "");
            else if (c == backup)
                entity.getProps().put("backup", backup.getValue());
            else if (c == dateFormat)
                entity.getProps().put("dateFormat", dateFormat.getValue());
            else if (c == expression)
                entity.getProps().put("expression", expression.getValue());
            else if (c == user)
                entity.getProps().put("user", user.getValue());
            else if (c == org)
                entity.getProps().put("org", org.getValue());
            else if (c == delay)
                entity.getProps().put("delay", delay.getValue() + "");
            else if (c == logic)
                entity.getProps().put("logic", logic.getValue());
            else if (c == onBefore)
                entity.getProps().put("onBefore", onBefore.getValue());
            else if (c == onAfter)
                entity.getProps().put("onAfter", onAfter.getValue());
            setDirty();
        } else if (evt.getName().equals(Events.ON_OPEN)||evt instanceof KeyEvent) {
            if (c == expression) {
                if (!Strings.isBlank(expression.getValue())) {
                    try {
                        new CronExpression(expression.getValue());
                    } catch (Exception ex) {
                        WebUtils.showError(Labels.getLabel(
                                "editor.resource.expression.invalid",
                                new Object[]{expression.getValue()}));
                        return;
                    }
                }
                AbstractView.createCronView(
                        new BandboxCallback(expression, Labels
                                .getLabel("editor.resource.expression")
                                + Labels.getLabel("menu.preference")))
                        .doHighlighted();
            } else if (c == task) {
                if (evt instanceof OpenEvent){
                    ((Bandbox) c).setValue(((OpenEvent)evt).getValue()+"");
                }
                AbstractView.createEntityView(new BandboxCallback(this, task),
                        EntityType.TASK.getName(), c).doOverlapped();
            } else if (c == logic || c == onBefore || c == onAfter) {
                if (evt instanceof OpenEvent){
                    ((Bandbox) c).setValue(((OpenEvent)evt).getValue()+"");
                }
                AbstractView.createEntityView(new BandboxCallback(this, (Bandbox) c),
                        EntityType.LOGIC.getName(), c).doOverlapped();
            } else if (c == user) {
                BizQueryVo vo = new BizQueryVo();
                vo.setSearchField("userId,name");
                vo.setOrderBy("userId");
                vo.setSql("SELECT userId,name FROM sys_user_info");
                vo.setParams(new FieldVo[0]);
                AbstractView.createQueryView(
                        new BandboxCallback(user, Labels.getLabel("menu.user")
                                + Labels.getLabel("menu.preference")), vo,
                        false, c, "ID", Labels.getLabel("entity.name"))
                        .doOverlapped();
            } else if (c == org) {
                BizQueryVo vo = new BizQueryVo();
                vo.setSearchField("orgId,name");
                vo.setOrderBy("orgId");
                vo.setSql("SELECT orgId,name FROM sys_org_info");
                vo.setParams(new FieldVo[0]);
                AbstractView.createQueryView(
                        new BandboxCallback(org, Labels.getLabel("menu.org")
                                + Labels.getLabel("menu.preference")), vo,
                        false, c, "ID", Labels.getLabel("entity.name"))
                        .doOverlapped();
            }

        } else if (evt.getName().equals(Events.ON_CHECK)) {
            if (c == checkHoliday)
                entity.getProps().put("checkHoliday",
                        checkHoliday.isChecked() + "");
            else if (c == immediate)
                entity.getProps().put("immediate", immediate.isChecked() + "");
            setDirty();
        }
    }

    @Override
    protected boolean validate() {
        if (Strings.isBlank(entity.getName())) {
            WebUtils.notEmpty(Labels.getLabel("entity.name"));
            return false;
        }
        if (Strings.isBlank(expression.getValue())) {
            WebUtils.notEmpty(Labels.getLabel("editor.resource.expression"));
            return false;
        }
        try {
            new CronExpression(expression.getValue());
        } catch (Exception ex) {
            WebUtils.showError(Labels.getLabel(
                    "editor.resource.expression.invalid",
                    new Object[]{expression.getValue()}));
            return false;
        }
        if (delay.getValue() < 1) {
            WebUtils.notEmpty(Labels.getLabel("editor.resource.delay"));
            return false;
        }
        if (clazz.getSelectedIndex() == 0) {
            if (Strings.isBlank(task.getValue())) {
                WebUtils.notEmpty(Labels.getLabel("entity.task"));
                return false;
            }
        } else if (clazz.getSelectedIndex() == 1) {
            if (Strings.isBlank(path.getValue())) {
                WebUtils.notEmpty(Labels.getLabel("editor.resource.file.path"));
                return false;
            }
        }
        return true;
    }
}
